package com.xbongbong.paas.toolbox.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Objects;

/**
 * TODO 只是拷过来，后续把本工具类替换掉
 */
@Deprecated
public class HttpUtil {
	private static final Logger LOG = LoggerFactory.getLogger(HttpUtil.class);
 
	public static void ajaxOut(HttpServletRequest request,
                               HttpServletResponse response, Map<String, Object> resultMap)
			throws IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		String callback = request.getParameter("callback");
		callback = StringUtil.replaceHtmlTag(callback);//过滤callback里的非法攻击脚本
		if (callback == null) {
			callback = "data";
		}
		PrintWriter out = response.getWriter();
		String rs = JSON.toJSONString(resultMap);
		out.write(callback + "(" + rs + ");");// 账户没有设定uid
	}
	
	/**
	 * 输出json
	 * @param request
	 * @param response
	 * @param resultMap
	 * @throws IOException
	 */
	public static String jsonOut(HttpServletRequest request,
                                 HttpServletResponse response, Map<String, Object> resultMap)
			throws IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("application/json");
		PrintWriter out = response.getWriter();
		String rs = JSON.toJSONString(resultMap);
		out.write(rs);// 账户没有设定uid
		return null;
	}
	
	/**
	 * 好像服务器返回的json格式，客户端还是要eval，弃用
	 * @param request
	 * @param response
	 * @param resultMap
	 * @throws IOException
	 * @throws JSONException
	 */
	public static void ajaxOutJSONObject(HttpServletRequest request,
                                         HttpServletResponse response, Map<String, Object> resultMap)
			throws IOException, JSONException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		String callback = request.getParameter("callback");
		callback = StringUtil.replaceHtmlTag(callback);//过滤callback里的非法攻击脚本
		LOG.debug("in ajaxout callback=" + callback);
		PrintWriter out = response.getWriter();
		JSONObject rj = new JSONObject(resultMap);
		out.write(callback + "(" + rj + ");");// 账户没有设定uid
	}
	
	/**
	 * ajax返回json格式数据
	 * @param request
	 * @param response
	 * @param str
	 * @throws IOException
	 */
	public static void ajaxOut(HttpServletRequest request,
                               HttpServletResponse response, String str)
			throws IOException {
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		String callback = request.getParameter("callback");
		callback = StringUtil.replaceHtmlTag(callback);//过滤callback里的非法攻击脚本
		LOG.debug("in ajaxout callback=" + callback);
		PrintWriter out = response.getWriter();
		String rs = JSON.toJSONString(str);
		out.write(callback + "(" + rs + ");");
	}

	public static boolean isAjaxRequest(HttpServletRequest request) {
		String requestType = request.getHeader("X-Requested-With");
		if (Objects.equals(requestType, "XMLHttpRequest")) {
			return true;
		} else {
			return false;
		}
	}
	
	public static String JSONRequest(String url) {
		HttpClient client = new HttpClient();
	    HttpMethod method=new GetMethod(url);
	    String response="";
	    try {
	    	  int statusCode= client.executeMethod(method);
	    	  if (statusCode == HttpStatus.SC_OK) {
	    		  response=method.getResponseBodyAsString();
	    	  }
		} catch (  IOException e) {

			e.printStackTrace();
		} finally {
			method.releaseConnection();
		}
		return response;
	}
	 
	public static String post(String apiUrl, Map<String, Object> params) {

		if (StringUtil.isEmpty(apiUrl)) {
			return null;
		}
		if (params == null) {
			return null;
		}
		String paramStr = CommentUtil.mapToUrl(params).substring(3);//JsonUtil.toJson(params);
		try {
			// Configure and open a connection to the site you will send the
			// request
			URL url = new URL(apiUrl);
			URLConnection urlConnection = url.openConnection();
			// 设置doOutput属性为true表示将使用此urlConnection写入数据
			urlConnection.setDoOutput(true);
			// 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
			urlConnection.setRequestProperty("content-type","application/x-www-form-urlencoded");
			// 得到请求的输出流对象
			OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream(), "utf-8");
			// 把数据写入请求的Body
			out.write(paramStr);
			out.flush();
			out.close();

			// 从服务器读取响应
			InputStream inputStream = urlConnection.getInputStream();
			// String encoding = urlConnection.getContentEncoding();
			return IOUtils.toString(inputStream, "utf-8");
		} catch (IOException e) {
			LOG.error("post异常", e);
		}

		return null;
	}
	
	/**
	 * post 传输字节流
	 * @param apiUrl
	 * @param bytes
	 * @return
	 */
	public static String post(String apiUrl, byte[] bytes) {

		if (StringUtil.isEmpty(apiUrl)) {
			return null;
		}
		if (bytes == null) {
			return null;
		}
		
		try {
			// Configure and open a connection to the site you will send the
			// request
			String boundary = "------WebKitFormBoundaryUey8ljRiiZqhZHBu";
			byte[] end_data = ("\r\n--" + boundary + "--\r\n").getBytes();// 定义最后数据分隔线  
			URL url = new URL(apiUrl);
			URLConnection urlConnection = url.openConnection();
			// 设置doOutput属性为true表示将使用此urlConnection写入数据
			urlConnection.setDoOutput(true);
			// 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
//			urlConnection.setRequestProperty("content-type","application/x-www-form-urlencoded");
			urlConnection.setRequestProperty("content-type","multipart/form-data;   boundary=" + boundary);
			// 得到请求的输出流对象
			OutputStream out = new DataOutputStream(urlConnection.getOutputStream());
			StringBuilder sb = new StringBuilder();
//            添加form属性  
//            sb.append("--");  
//            sb.append(boundary);  
//            sb.append("\r\n");  
//            sb.append("Content-Disposition: form-data; name=\"username\"");  
//            sb.append("\r\n\r\n");  
//            sb.append("hello word");  
//            out.write(sb.toString().getBytes("utf-8"));  
//            out.write("\r\n".getBytes("utf-8"));
            
            String fname = "pic1";
            sb = new StringBuilder();
            sb.append("--");  
            sb.append(boundary);  
            sb.append("\r\n");  
            sb.append("Content-Disposition: form-data;name=\"file1"  
                    + "\";filename=\"" + fname + "\"\r\n");  
            sb.append("Content-Type:application/octet-stream\r\n\r\n");  
            byte[] data = sb.toString().getBytes();  
            out.write(data);
            // 把数据写入请求的Body
         	out.write(bytes);
            out.write("\r\n".getBytes()); // 多个文件时，二个文件之间加入这个  
            out.write(end_data);
			
			out.flush();
			out.close();

			// 从服务器读取响应
			InputStream inputStream = urlConnection.getInputStream();
			// String encoding = urlConnection.getContentEncoding();
			return IOUtils.toString(inputStream, "utf-8");
		} catch (IOException e) {
			LOG.error("post异常", e);
		}

		return null;
	}
	
	public static String postHttps(String url, String params) {
        StringBuffer bufferRes = null;
        try {
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象  
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL urlGet = new URL(url);
            HttpsURLConnection http = (HttpsURLConnection) urlGet.openConnection();
            // 连接超时
            http.setConnectTimeout(25000);
            // 读取超时 --服务器响应比较慢，增大时间
            http.setReadTimeout(25000);
            http.setRequestMethod("POST");
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setSSLSocketFactory(ssf);
            http.setDoOutput(true);
            http.setDoInput(true);
            http.connect();

            OutputStream out = http.getOutputStream();
            out.write(params.getBytes("UTF-8"));
            out.flush();
            out.close();

            InputStream in = http.getInputStream();
            BufferedReader read = new BufferedReader(new InputStreamReader(in, "utf-8"));
            String valueString = null;
            bufferRes = new StringBuffer();
            while ((valueString = read.readLine()) != null){
                bufferRes.append(valueString);
            }
            in.close();
            if (http != null) {
                // 关闭连接
                http.disconnect();
            }
            return bufferRes.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
	
	

	/**
	 * 向指定URL发送GET方法的请求
	 * 
	 * @param url
	 *            发送请求的URL
	 * @param params
	 *            请求参数，请求参数应该是name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public static String getHttps(String url, Map<String, Object> params) {
		String result = "";
		BufferedReader in = null;
		try {
			String urlName = url + CommentUtil.mapToUrl(params);
			URL realUrl = new URL(urlName);
			
			TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
			{
				@Override
				public java.security.cert.X509Certificate[] getAcceptedIssuers()
				{
						return null;
				}
				@Override
				public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
				{
				}

				@Override
				public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
				{
				}
			}};
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
//			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
			

			HostnameVerifier hv = new HostnameVerifier()
			{
				@Override
			      public boolean verify(String urlHostName, SSLSession session)
			      {
			             return true;
			      }
			};
			
//			HttpsURLConnection.setDefaultHostnameVerifier(hv);

			// 打开和URL之间的连接
			HttpsURLConnection conn = (HttpsURLConnection)realUrl.openConnection();
			conn.setHostnameVerifier(hv);
			conn.setSSLSocketFactory(sc.getSocketFactory());
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			// 建立实际的连接
			conn.connect();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream(), "utf-8"));
			String line;
			while ((line = in.readLine()) != null) {
				result += "\n" + line;
			}
		} catch (Exception e) {
			LOG.error("发送GET请求出现异常！", e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}
	
	
	
	/**
	 * 向指定URL发送GET方法的请求
	 * 
	 * @param apiUrl
	 *            发送请求的URL
	 * @param params
	 *            请求参数，请求参数应该是name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public static String get(String apiUrl, Map<String, Object> params) {
		String result = "";
		BufferedReader in = null;
		try {
			String urlName = apiUrl + CommentUtil.mapToUrl(params);
			URL url = new URL(urlName);
			LOG.info("url  ===========" + url);
			// 打开和URL之间的连接
			URLConnection conn = url.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			// 建立实际的连接
			conn.connect();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream(), "utf-8"));
			String line;
			while ((line = in.readLine()) != null) {
				if("".equals(result)) {
					result = line;
				} else {
					result += "\n" + line;
				}			
			}
			
		} catch (Exception e) {
			LOG.error("发送GET请求出现异常！", e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	} 
	
	/**
	 * 向指定URL发送GET方法的请求
	 * 
	 * @param apiUrl
	 *            发送请求的URL
	 * @param params
	 *            请求参数，请求参数应该是name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public static String get(String apiUrl, Map<String, Object> params, String charSet) {
		String result = "";
		BufferedReader in = null;
		try {
			String urlName = apiUrl + CommentUtil.mapToUrl(params);
			URL url = new URL(urlName);
			// 打开和URL之间的连接
			URLConnection conn = url.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			// 建立实际的连接
			conn.connect();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(
					new InputStreamReader(conn.getInputStream(), charSet));
			String line;
			while ((line = in.readLine()) != null) {
				if("".equals(result)) {
					result = line;
				} else {
					result += "\n" + line;
				}			
			}
			
		} catch (Exception e) {
			LOG.error("发送GET请求出现异常！", e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	} 
	
	public static String getHttpResponse(String url){
		HttpClient client = new HttpClient(); 
	    HttpMethod method=new GetMethod(url);
	    String result;
	    try {
	    	  int statusCode= client.executeMethod(method);
	    	  if (statusCode == HttpStatus.SC_OK) {
	    		  result= null;
	    		InputStream in= method.getResponseBodyAsStream();
	    		result = getString(in);
	    	  } else{
	    		  result ="http no response";
	    	  }
		} catch (  IOException e) {
			e.printStackTrace();
			result="IOException";
		} finally {
			method.releaseConnection();
		}
	    return result;
	}

	public static String getString(InputStream in){
		 BufferedReader br;
		try {
			br = new BufferedReader(new InputStreamReader(in,"gb2312"));
		} catch (UnsupportedEncodingException e1) {

			e1.printStackTrace();
			return "";
		}  
	        StringBuffer resBuffer = new StringBuffer();
	        String resTemp = "";
	        try {
				while((resTemp = br.readLine()) != null){  
				    resBuffer.append(resTemp);  
				}
			} catch (IOException e) {
				e.printStackTrace();
				return "";
			}  
	        String response = resBuffer.toString();
	        return response;
	}
	
	/**
	 * android : 所有android设备
	 * mac os : iphone ipad
	 * windows phone:Nokia等windows系统的手机
	 */
	public static boolean   isMobileDevice(String requestHeader) {
		String[] deviceArray = new String[]{"android","iphone","ipad","ipod","windows phone"};
		if(requestHeader == null) {
			return false;
		}
		requestHeader = requestHeader.toLowerCase();
		for(int i=0;i<deviceArray.length;i++){
			if(requestHeader.indexOf(deviceArray[i])>0){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 获取当前完整url，包括参数部分
	 * @param request
	 * @return
	 */
	public static String getCurrentUrlStr(HttpServletRequest request) {
		String url = request.getRequestURL().toString();
		String queryString = request.getQueryString();
		if (StringUtil.isEmpty(queryString)) {
			return url;
		}
		return url + "?" + queryString;
	}
	
	/**
	 * 获取域名和端口
	 * @param request
	 * @return
	 */
	public static String getBaseUrl(HttpServletRequest request) {
		
		String basePath = request.getScheme()+"://"+request.getServerName();
		if(request.getServerPort() != 80  && request.getServerPort() != 443){
			basePath+= ":"+request.getServerPort();
		}
		basePath += request.getContextPath();

		return basePath;
	}
	
	/**
	 * 向指定URL直接发送postData
	 * 
	 * @param apiUrl
	 *            发送请求的URL
	 * @param postData
	 *            发送的数据
	 *            @param contentType "json" 或者为空即"x-www-form-urlencoded"
	 * @return URL所代表远程资源的响应
	 */
	public static String post(String apiUrl, String postData, String contentType ) {

		if (StringUtil.isEmpty(apiUrl)) {
			return null;
		}
		if (postData == null) {
			return null;
		}
		
		if("json".equals(contentType)){
			contentType="application/json";
		}else{
			contentType="application/x-www-form-urlencoded";
		}
		try {
			// Configure and open a connection to the site you will send the
			// request
			URL url = new URL(apiUrl);
			URLConnection urlConnection = url.openConnection();
			// 设置doOutput属性为true表示将使用此urlConnection写入数据
			urlConnection.setDoOutput(true);
			// 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
			urlConnection.setRequestProperty("content-type",contentType);
			// 得到请求的输出流对象
			OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream(), "utf-8");
			// 把数据写入请求的Body
			out.write(postData);
			out.flush();
			out.close();

			// 从服务器读取响应
			InputStream inputStream = urlConnection.getInputStream();
			// String encoding = urlConnection.getContentEncoding();
			return IOUtils.toString(inputStream, "utf-8");
		} catch (IOException e) {
			LOG.error("post异常", e);
		}

		return null;
	}
	public static String post(String apiUrl, String postData) {
		return post(apiUrl,postData,null);
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		File file = new File("http://www.lagou.com/app/download-pc-b/images/page1-1V2.png");

		System.out.println("apiurl=========" + file.getPath());


		InputStream in = null;
		try {
			in = new FileInputStream(file);
			int i = in.available(); // 得到文件大小
			byte data[] = new byte[i];
			in.read(data); // 读数据
			in.close();

			Base64 base64 = new Base64();
			String a = base64.encodeToString(data);
			System.out.println(a);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(Objects.nonNull(in)) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

//证书管理
class MyX509TrustManager implements X509TrustManager {
		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
		}
}

